home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Freeware 25 / FreelogHS25.iso / Dessin / ArtOfIllusion2.2.1 / Scripts / Tools / Platonic Solid.bsh < prev    next >
Text File  |  2005-06-11  |  15KB  |  392 lines

  1. /*
  2. <?xml version='1.0' standalone='yes' ?>
  3.  
  4. <script>
  5.     <name>Platonic Solid</name>
  6.     <author>Fran∩┐╜ois Guillet</author>
  7.     <version>1.81</version>
  8.     <date>06/25/2004</date>
  9.     <description>
  10. This script creates one of the five platonic solids:
  11. tetrahedron, hexahedron, octahedron, dodecahedron, icosahedron.
  12. The polyhedron created consists of a triangular mesh
  13. with an optional vertex at the center of each face
  14. after "Geometric Tools for Computer Graphics", Philip J. Schneider and David H. Eberly, pp 346-351
  15. Morgan and Kaufmann 2003
  16.     </description>
  17. </script>
  18. */
  19.  
  20. /* Copyright (C) 2004 by Fran∩┐╜ois Guillet
  21.  
  22.    This program is free software; you can redistribute it and/or modify it under the
  23.    terms of the GNU General Public License as published by the Free Software
  24.    Foundation; either version 2 of the License, or (at your option) any later version.
  25.  
  26.    This program is distributed in the hope that it will be useful, but WITHOUT ANY 
  27.    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
  28.    PARTICULAR PURPOSE.  See the GNU General Public License for more details. */
  29.    
  30. //Script localization test
  31.  
  32. HashMap translations = new HashMap();
  33. if (Translate.getLocale().equals(Locale.FRENCH))
  34. {
  35.          translations.put("Hexahedron", "Hexah\u00E8dre (6)");
  36.          translations.put("Tetrahedron", "Tetrah\u00E8dre (4)");
  37.          translations.put("Octahedron", "Octah\u00E8dre (8)");
  38.          translations.put("Dodecahedron", "Dodecah\u00E8dre (12)");
  39.          translations.put("Icosahedron", "Icosah\u00E8dre (20)");
  40.          translations.put("centeredFaces", "sommets aux centres des faces");
  41.          translations.put("selectPolyhedron", "S\u00E9lectionnez un polyh\u00E8dre :");
  42.          translations.put("noSmoothing", "Pas de lissage" );
  43.          translations.put("smoothShading", "Ombrage doux" );
  44.          translations.put("interpolating", "Interpolation" );
  45.          translations.put("approximating", "Approximation" );
  46.          translations.put("polyhedron", "Polyh\u00E8dre:" );
  47.          translations.put("faceCenteredMesh", "Maillage face centr\u00E9e" );
  48.          translations.put("radius", "Rayon :" );
  49.          translations.put("smoothingMethod", "M\u00E9thode de lissage:");
  50.          translations.put("verticesSmoothness", "Lissage des sommets :");
  51.          translations.put("edgesSmoothness", "Lissages des ar\u00EAtes :");
  52.          translations.put("texture", "Texture :");
  53.          translations.put("material", "Mat\u00E9riau :");
  54.          translations.put("hexahedron", "Hexah\u00E8dre");
  55.          translations.put("tetrahedron", "Tetrah\u00E8dre");
  56.          translations.put("octahedron", "Octah\u00E8dre");
  57.          translations.put("dodecahedron", "Dodecah\u00E8dre");
  58.          translations.put("icosahedron", "Icosah\u00E8dre");
  59. }
  60. else
  61. {
  62.          translations.put("Hexahedron", "Hexahedron (6)");
  63.          translations.put("Tetrahedron", "Tetrahedron (4)");
  64.          translations.put("Octahedron", "Octahedron (8)");
  65.          translations.put("Dodecahedron", "Dodecahedron (12)");
  66.          translations.put("Icosahedron", "Icosahedron (20)");
  67.          translations.put("centeredFaces", "vertices at faces centers");
  68.          translations.put("selectPolyhedron", "Select a polyhedron:");
  69.          translations.put("noSmoothing", "No Smoothing" );
  70.          translations.put("smoothShading", "Smooth Shading" );
  71.          translations.put("interpolating", "Interpolating" );
  72.          translations.put("approximating", "Approximating" );
  73.          translations.put("polyhedron", "Polyhedron:" );
  74.          translations.put("faceCenteredMesh", "Face centered mesh" );
  75.          translations.put("radius", "Radius:" );
  76.          translations.put("smoothingMethod", "Smoothing Method:");
  77.          translations.put("verticesSmoothness", "Vertices Smoothness:");
  78.          translations.put("edgesSmoothness", "Edges smoothness:");
  79.          translations.put("texture", "Texture:");
  80.          translations.put("material", "Material:");
  81.          translations.put("hexahedron", "Hexahedron");
  82.          translations.put("tetrahedron", "Tetrahedron");
  83.          translations.put("octahedron", "Octahedron");
  84.          translations.put("dodecahedron", "Dodecahedron");
  85.          translations.put("icosahedron", "Icosahedron");
  86. }
  87. //end of script localization test
  88.    
  89.    
  90. //given a set of faces, this function computes the centers of the faces and adds them to the list of vertices
  91. Vec3[] completeVertices(Vec3[] vert, int[][] polyFaces, int vertNum)
  92. {    vertices = new Vec3[vert.length + polyFaces.length];
  93.     
  94.     for (i = 0 ; i < vert.length ; ++i)
  95.         vertices[i] = vert[i];
  96.     
  97.     for (i = vertNum; i < vertNum + polyFaces.length; ++i)
  98.     {    v = new Vec3();
  99.         for (j = 0 ; j < polyFaces[i - vertNum].length; ++j)
  100.             v.add(vertices[polyFaces[i - vertNum][j]]);
  101.         v.scale(1.0/polyFaces[i - vertNum].length);
  102.         vertices[i] = v;
  103.     }
  104.     
  105.     return vertices;
  106. }
  107.  
  108. //given a set of faces and a set of vertices,
  109. //this function computes centered faces to form a triangular mesh
  110. //presumably equivalent to subdivide face command in the mesh editor
  111. TriangleMesh triangulateFaces(Vec3[] vertices, int[][] polyFaces, int vertNum)
  112. {    vertices = completeVertices(vertices, polyFaces, vertNum);
  113.     
  114.     faces = new int[polyFaces.length * polyFaces[0].length][3];
  115.     
  116.     f = 0;
  117.     for (i = 0 ; i < polyFaces.length ; ++i)
  118.     {    for (j = 0; j < polyFaces[i].length ; ++j)
  119.         {    if (j < polyFaces[i].length-1)
  120.             {    faces[f][0] = polyFaces[i][j];
  121.                 faces[f][1] = polyFaces[i][j+1];
  122.                 faces[f][2] = vertNum + i;
  123.             }
  124.             else
  125.             {    faces[f][0] = polyFaces[i][j];
  126.                 faces[f][1] = polyFaces[i][0];
  127.                 faces[f][2] = vertNum + i;
  128.             }
  129.             ++f;
  130.         }
  131.     }
  132.     mesh = new TriangleMesh(vertices, faces);
  133.     return mesh;
  134. }
  135.  
  136.  
  137. scene = window.getScene();
  138.  
  139. //setup the list of polyhedra
  140. polyList = new BList(new String [] {
  141.     translations.get("Tetrahedron"),
  142.     translations.get("Hexahedron"),
  143.     translations.get("Octahedron"),
  144.     translations.get("Dodecahedron"),
  145.     translations.get("Icosahedron")
  146. });
  147. polyList.setPreferredVisibleRows(5);
  148. polyList.setSelected(0, true);
  149.  
  150. //face centered checkbox
  151. centeredCheckbox = new BCheckBox(translations.get("centeredFaces"), false);
  152.  
  153. //radius value field
  154. radiusValueField = new ValueField(1.0, ValueField.NONNEGATIVE);
  155.  
  156. //smoothing method
  157. smoothList = new BList(new String [] {
  158.     translations.get("noSmoothing"),
  159.     translations.get("smoothShading"),
  160.     translations.get("interpolating"),
  161.     translations.get("approximating")
  162. });
  163. smoothList.setPreferredVisibleRows(4);
  164. smoothList.setSelected(0, true);
  165.  
  166. //vertices smoothness value field
  167. vertSmoothnessValueField = new ValueField(1.0, ValueField.NONNEGATIVE);
  168.  
  169. //edges smoothness value field
  170. edgesSmoothnessValueField = new ValueField(1.0, ValueField.NONNEGATIVE);
  171.  
  172. // get list of scene textures
  173. numTex=scene.getNumTextures();
  174. textureList=new BList();
  175. textureList.setPreferredVisibleRows(3 < numTex ? 3 : numTex);
  176. for (i = 0 ; i < numTex ; i++)
  177. {
  178.    iTex=scene.getTexture(i);
  179.    name=iTex.getName();
  180.    textureList.add(name);
  181. }
  182. textureList.setSelected(0, true);
  183.  
  184. // get list of materials
  185. numMat=scene.getNumMaterials();
  186. materialList=new BList();
  187. materialList.setPreferredVisibleRows(3 < numMat + 1 ? 3 : numMat + 1);
  188. materialList.add("none");
  189. for (i = 0 ; i < numMat ; i++)
  190. {
  191.    iMat=scene.getMaterial(i);
  192.    name=iMat.getName();
  193.    materialList.add(name);
  194. }
  195. materialList.setSelected(0, true);
  196.  
  197.  
  198. dlg = new ComponentsDialog(window, translations.get("selectPolyhedron"),
  199. new Widget [] { UIUtilities.createScrollingList(polyList), centeredCheckbox, radiusValueField, UIUtilities.createScrollingList(smoothList), vertSmoothnessValueField, edgesSmoothnessValueField, UIUtilities.createScrollingList(textureList), UIUtilities.createScrollingList(materialList)},
  200. new String [] { translations.get("polyhedron"), translations.get("faceCenteredMesh"), translations.get("radius"), translations.get("smoothingMethod"), translations.get("verticesSmoothness"), translations.get("edgesSmoothness"), translations.get("texture"), translations.get("material") } );
  201.  
  202. if (!dlg.clickedOk()) return;
  203.  
  204. centered = centeredCheckbox.getState();
  205.  
  206. switch (polyList.getSelectedIndex())
  207. {    case 0 : //tetrahedra
  208.         vertices = new Vec3[4]; // 4 vertices + 4 faces
  209.         vertices[0] = new Vec3(0, 0, 1);
  210.         vertices[1] = new Vec3(2*Math.sqrt(2)/3, 0, -1.0/3.0);
  211.         vertices[2] = new Vec3(-Math.sqrt(2)/3, Math.sqrt(6)/3, -1.0/3.0);
  212.         vertices[3] = new Vec3(-Math.sqrt(2)/3, -Math.sqrt(6)/3, -1.0/3.0);
  213.         int[][] faces = {{ 0, 1, 2 },  { 0, 2, 3 }, { 0, 3, 1 }, { 1, 3, 2 }};
  214.         if (centered)
  215.             mesh = triangulateFaces(vertices, faces, 4);
  216.         else
  217.             mesh = new TriangleMesh(vertices, faces);
  218.         name = translations.get("tetrahedron") + (centered ? " FC" : "");
  219.         break;
  220.         
  221.     case 1 : //hexahedron
  222.         vertices = new Vec3[8]; // 8 vertices + 6 faces
  223.         vertices[0] = new Vec3(-1, -1, -1);
  224.         vertices[1] = new Vec3(1, -1, -1);
  225.         vertices[2] = new Vec3(1, 1, -1);
  226.         vertices[3] = new Vec3(-1, 1, -1);
  227.         vertices[4] = new Vec3(-1, -1, 1);
  228.         vertices[5] = new Vec3(1, -1, 1);
  229.         vertices[6] = new Vec3(1, 1, 1);
  230.         vertices[7] = new Vec3(-1, 1, 1);
  231.         for (i = 0 ; i < 8 ; ++i)
  232.             vertices[i].scale(1.0/Math.sqrt(3));
  233.         
  234.         //polygon faces when different from triangular faces
  235.         int[][] hexaFaces = {{ 0, 3, 2, 1 },  { 0, 1, 5, 4 }, { 0, 4, 7, 3 },
  236.             { 6, 5, 1, 2 }, { 6, 2, 3, 7 }, { 6, 7, 4, 5 } };
  237.         
  238.         //triangular faces
  239.         int[][] faces = {{ 0, 3, 2}, { 0, 2, 1}, { 0, 1, 5}, { 0, 5, 4}, { 0, 4, 7}, {0, 7, 3},
  240.             { 6, 5, 1}, { 6, 1, 2}, { 6, 2, 3}, { 6, 3, 7}, { 6, 7, 4}, {6, 4, 5}};
  241.         if (centered)
  242.             mesh = triangulateFaces(vertices, hexaFaces, 8);
  243.         else 
  244.             mesh = new TriangleMesh(vertices, faces);
  245.         name = translations.get("hexahedron") + (centered ? " FC" : "");
  246.         break;
  247.         
  248.     case 2 : //octahedron
  249.         vertices = new Vec3[6]; // 6 vertices + 8 faces
  250.         vertices[0] = new Vec3(1, 0, 0);
  251.         vertices[1] = new Vec3(-1, 0, 0);
  252.         vertices[2] = new Vec3(0, 1, 0);
  253.         vertices[3] = new Vec3(0, -1, 0);
  254.         vertices[4] = new Vec3(0, 0, 1);
  255.         vertices[5] = new Vec3(0, 0, -1);
  256.         
  257.         int[][] faces = {
  258.             { 4, 0, 2 }, { 4, 2, 1 }, { 4, 1, 3 }, { 4, 3, 0 }, 
  259.             { 5, 2, 0 }, { 5, 1, 2 }, { 5, 3, 1 }, { 5, 0, 3 }
  260.         };
  261.         
  262.          if (centered)
  263.             mesh = triangulateFaces(vertices, faces, 6);
  264.         else
  265.             mesh = new TriangleMesh(vertices, faces);
  266.         
  267.         name = translations.get("octahedron") + (centered ? " FC" : "");
  268.         break;
  269.     
  270.     case 3 : //dodecahedron
  271.         vertices = new Vec3[20]; // 20 vertices + 12 faces
  272.         a = 1/Math.sqrt(3);
  273.         b = Math.sqrt( (3.0 - Math.sqrt(5)) /6.0);
  274.         c = Math.sqrt( (3.0 + Math.sqrt(5)) /6.0);
  275.         vertices[0] = new Vec3(a, a, a);
  276.         vertices[1] = new Vec3(a, a, -a);
  277.         vertices[2] = new Vec3(a, -a, a);
  278.         vertices[3] = new Vec3(a, -a, -a);
  279.         vertices[4] = new Vec3(-a, a, a);
  280.         vertices[5] = new Vec3(-a, a, -a);
  281.         vertices[6] = new Vec3(-a, -a, a);
  282.         vertices[7] = new Vec3(-a, -a, -a);
  283.         vertices[8] = new Vec3(b, c, 0);
  284.         vertices[9] = new Vec3(-b, c, 0);
  285.         vertices[10] = new Vec3(b, -c, 0);
  286.         vertices[11] = new Vec3(-b, -c, 0);
  287.         vertices[12] = new Vec3(c, 0, b);
  288.         vertices[13] = new Vec3(c, 0, -b);
  289.         vertices[14] = new Vec3(-c, 0, b);
  290.         vertices[15] = new Vec3(-c, 0, -b);
  291.         vertices[16] = new Vec3(0, b, c);
  292.         vertices[17] = new Vec3(0, -b, c);
  293.         vertices[18] = new Vec3(0, b, -c);
  294.         vertices[19] = new Vec3(0, -b, -c);
  295.         
  296.         int[][] faces = { //*quite* dull
  297.             { 0, 8, 9 }, { 0, 12, 13 }, { 0, 16, 17 }, { 8, 1, 18 }, 
  298.             { 12, 2, 10 }, { 16, 4, 14 }, { 9, 5, 15 }, { 6, 11, 10 },
  299.             { 3, 19, 18 }, { 7, 15, 5 }, { 7, 11, 6 }, { 7, 19, 3 },
  300.             { 0, 9, 4 }, { 0, 13, 1 }, { 0, 17, 2 }, { 8, 18, 5 }, 
  301.             { 12, 10, 3 }, { 16, 14, 6 }, { 9, 15, 14 }, { 6, 10, 2 },
  302.             { 3, 18, 1 }, { 7, 5, 18 }, { 7, 6, 14 }, { 7, 3, 10 },
  303.             { 0, 4, 16 }, { 0, 1, 8 }, { 0, 2, 12 }, { 8, 5, 9 }, 
  304.             { 12, 3, 13 }, { 16, 6, 17 }, { 9, 14, 4 }, { 6, 2, 17 },
  305.             { 3, 1, 13 }, { 7, 18, 19 }, { 7, 14, 15 }, { 7, 10, 11 }
  306.         };
  307.         
  308.         int[][] dodeFaces = {
  309.             { 0, 8, 9, 4, 16}, { 0, 16, 17, 2, 12}, { 12, 2, 10, 3, 13},
  310.             { 9, 5, 15, 14, 4}, { 3, 19, 18, 1, 13}, { 7, 11, 6, 14, 15},
  311.             { 0, 12, 13, 1, 8}, { 8, 1, 18, 5, 9}, { 16, 4, 14, 6, 17},
  312.             { 6, 11, 10, 2, 17}, { 7, 15, 5, 18, 19}, { 7, 19, 3, 10, 11}
  313.         };
  314.         
  315.          if (centered)
  316.             mesh = triangulateFaces(vertices, dodeFaces, 20);
  317.         else
  318.             mesh = new TriangleMesh(vertices, faces);
  319.         
  320.         name = translations.get("dodecahedron") + (centered ? " FC" : "");
  321.         break;
  322.         
  323.    case 4 : //icosahedron
  324.         vertices = new Vec3[12]; // 12 vertices + 20 faces
  325.         t = ( 1.0 + Math.sqrt(5) )/2.0;
  326.         vertices[0] = new Vec3(t, 1, 0);
  327.         vertices[1] = new Vec3(-t, 1, -0);
  328.         vertices[2] = new Vec3(t, -1, 0);
  329.         vertices[3] = new Vec3(-t, -1, 0);
  330.         vertices[4] = new Vec3(1, 0, t);
  331.         vertices[5] = new Vec3(1, 0, -t);
  332.         vertices[6] = new Vec3(-1, 0, t);
  333.         vertices[7] = new Vec3(-1, 0, -t);
  334.         vertices[8] = new Vec3(0, t, 1);
  335.         vertices[9] = new Vec3(0, -t, 1);
  336.         vertices[10] = new Vec3(0, t, -1);
  337.         vertices[11] = new Vec3(0, -t, -1);
  338.         for (i = 0 ; i < 12 ; ++i)
  339.             vertices[i].scale( 1.0 / Math.sqrt( 1.0 + t*t) );
  340.         
  341.         int[][] faces = {
  342.             { 0, 8, 4 }, { 0, 5, 10 }, { 2, 4, 9 }, { 2, 11, 5 }, 
  343.             { 1, 6, 8 }, { 1, 10, 7 }, { 3, 9, 6 }, { 3, 7, 11 },
  344.             { 0, 10, 8 }, { 1, 8, 10 }, { 2, 9, 11 }, { 3, 11, 9 },
  345.             { 4, 2, 0 }, { 5, 0, 2 }, { 6, 1, 3 }, { 7, 3, 1 }, 
  346.             { 8, 6, 4 }, { 9, 4, 6 }, { 10, 5, 7 }, { 11, 7, 5 }
  347.         };
  348.         
  349.         
  350.         if (centered)
  351.             mesh = triangulateFaces(vertices, faces, 12);
  352.         else
  353.             mesh = new TriangleMesh(vertices, faces);
  354.         
  355.         name = translations.get("icosahedron") + (centered ? " FC" : "");
  356.         break;
  357.     default :
  358.         return;
  359. }
  360.  
  361. //set vertices smoothness and scale mesh in the process
  362. meshVertices = mesh.getVertices();
  363. radius = radiusValueField.getValue();
  364. for ( i = 0 ; i < meshVertices.length ; ++i)
  365. {    meshVertices[i].smoothness = (float) vertSmoothnessValueField.getValue();
  366.     meshVertices[i].r.scale(radius);
  367. }
  368.  
  369. //set edges smoothness
  370. meshEdges = mesh.getEdges();
  371. for ( i = 0 ; i < meshEdges.length ; ++i)
  372.     meshEdges[i].smoothness = (float) edgesSmoothnessValueField.getValue();
  373.  
  374. //set mesh smoothing method
  375. mesh.setSmoothingMethod(smoothList.getSelectedIndex());
  376.  
  377. //set texture
  378. tex = scene.getTexture(textureList.getSelectedIndex());
  379. mesh.setTexture(tex, tex.getDefaultMapping());
  380.  
  381. //set material
  382. matIndex = materialList.getSelectedIndex();
  383. if ( matIndex > 0 )
  384. {    mat = scene.getMaterial(matIndex-1);
  385.     mesh.setMaterial(mat, mat.getDefaultMapping());
  386. }
  387.  
  388. //we're done
  389. window.addObject(mesh, new CoordinateSystem(), name, null);
  390.  
  391.  
  392.